package cliente;

import java.util.Scanner;

import org.omg.CORBA.ORB;
import org.omg.CosNaming.NameComponent;
import org.omg.CosNaming.NamingContext;
import org.omg.CosNaming.NamingContextHelper;
import org.omg.CosNaming.NamingContextPackage.CannotProceed;
import org.omg.CosNaming.NamingContextPackage.InvalidName;
import org.omg.CosNaming.NamingContextPackage.NotFound;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import org.omg.PortableServer.POAManagerPackage.AdapterInactive;
import org.omg.PortableServer.POAPackage.ServantNotActive;
import org.omg.PortableServer.POAPackage.WrongPolicy;

import ClienteInterfaces.ClienteInterfacePOA;
import ServidorInterfaces.ServidorInterface;
import ServidorInterfaces.ServidorInterfaceHelper;

import transporte.Transporte;

public class Cliente extends ClienteInterfacePOA{

	private org.omg.CORBA.Object refServerMethod;
	private ServidorInterface servidor;

	private String nomeDoCliente;
	private boolean flag = false;

	public Cliente(String nomeDoCliente, String[] args){
		this.nomeDoCliente = nomeDoCliente;

		//inicializa o servidor de nomes e a referencia do objeto que esta no servidor de nomes
		ORB orb = ORB.init(args, null);		
		org.omg.CORBA.Object obj;

		try {			

			obj = orb.resolve_initial_references("NameService");
			NamingContext naming = NamingContextHelper.narrow(obj);
			NameComponent[] name = { new NameComponent("Chat", "Exemplo") };
			refServerMethod = naming.resolve(name);

			//registra cliente no servidor de nomes
			ORB orb2 = ORB.init(args, null);
			org.omg.CORBA.Object objPoa;
			objPoa = orb2.resolve_initial_references("RootPOA");			
			POA rootPOA = POAHelper.narrow(objPoa);

			org.omg.CORBA.Object obj2 = orb.resolve_initial_references("NameService");
			NamingContext naming2 = NamingContextHelper.narrow(obj2);

			org.omg.CORBA.Object objRef = rootPOA.servant_to_reference(this);
			NameComponent[] name2 = { new NameComponent(nomeDoCliente, "teste") };
			naming2.rebind(name2, objRef);

			servidor = ServidorInterfaceHelper.narrow(refServerMethod);
			servidor.insereCliente(nomeDoCliente);

			rootPOA.the_POAManager().activate();		

		} catch (org.omg.CORBA.ORBPackage.InvalidName e) {
			e.printStackTrace();
		} catch (NotFound e) {
			e.printStackTrace();
		} catch (CannotProceed e) {
			e.printStackTrace();
		} catch (InvalidName e) {
			e.printStackTrace();
		} catch (AdapterInactive e) {
			e.printStackTrace();
		} catch (ServantNotActive e) {
			e.printStackTrace();
		} catch (WrongPolicy e) {
			e.printStackTrace();
		}		
	}

	public void enviaMensagemIndidual(String nomeDestinatario, String msg){
		Transporte t = new Transporte();
		t.acao = "1";
		t.nomeCliente = this.nomeDoCliente;
		t.mensagem = msg;
		t.nomeDoDestinatario = nomeDestinatario;

		if(msg != null && !msg.equals("") && msg.length()!=0){
			enviaParaServidor(t.toString());
		}
	}

	public void enviaMensagemPraTodos(String msg){
		Transporte t = new Transporte();
		t.acao = "2";
		t.nomeCliente = this.nomeDoCliente;
		t.mensagem = msg;

		if(msg != null && !msg.equals("") && msg.length()!=0){
			enviaParaServidor(t.toString());
		}
	}

	public void notificaServidorStatus(String status){
		Transporte t = new Transporte();
		t.acao = "2";
		t.nomeCliente = this.nomeDoCliente;
		t.statusDoCliente = status;

		enviaParaServidor(t.toString());
	}

	@Override
	public void recebeDoServidor(String arg) {
		Transporte t = new Transporte();
		t.fromString(arg);

		Integer acao = Integer.parseInt(t.acao);

		switch(acao){

		case 4://Servidor envia mensagem para um cliente
			Transporte t4 = t;
			System.out.println(t4.nomeCliente+">> "+t4.mensagem);
			break;

		case 5: //
			Transporte t5 = t;
			System.out.println(t5.nomeCliente+">> "+t5.mensagem);
			break;

		default:
		}
	}

	@Override
	public void enviaParaServidor(String arg2) {
		servidor.recebeDoCliente(arg2);
	}	

	@Override
	public boolean isOn() {
		return flag;
	}

	public boolean isFlag() {
		return flag;
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}	

	public String getNomeDoCliente() {
		return nomeDoCliente;
	}

	@Override
	public String getNomeCliente() {
		// TODO Auto-generated method stub
		return null;
	}

	public static void main(String[] args) {

		Scanner scanner = new Scanner(System.in);
		System.out.print("Digite seu nome: ");
		String nome = scanner.next();

		Cliente c1 = new Cliente(nome,args);

		while(scanner.hasNext()){
			c1.enviaMensagemIndidual("tiago",scanner.nextLine());
		}
	}






}
